select函数实现TCP双向通信 |
您所在的位置:网站首页 › c语言 select函数 › select函数实现TCP双向通信 |
服务器通信实现代码 #include "myhead.h" /* tcp双向通信--》服务器的代码 多路复用使用思路: 1.思考要监测什么文件描述符 --》新的套接字(接收) --》键盘(发生) 2.监测新套接字的读就绪 监测键盘的读就绪 */ int main() { int tcpsock; int newsock; int ret; char rbuf[100]; char sbuf[100]; //定义ipv4地址体变量存放需要绑定的ip和端口号 struct sockaddr_in bindaddr; bzero(&bindaddr,sizeof(bindaddr)); bindaddr.sin_family=AF_INET; bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //女朋友(服务器)自己的ip bindaddr.sin_port=htons(20000); //女朋友(服务器)的端口号 //定义ipv4地址体变量存放客户端的ip和端口号 struct sockaddr_in boyaddr; int addrsize=sizeof(boyaddr); //创建tcp套接字 tcpsock=socket(AF_INET,SOCK_STREAM,0); if(tcpsock==-1) { perror("创建tcp套接字失败!\n"); return -1; } int on=1; setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); //绑定女朋友(服务器)自己的ip和端口号 ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr)); if(ret==-1) { perror("绑定ip端口失败了!\n"); return -1; } //监听 ret=listen(tcpsock,5); if(ret==-1) { perror("监听失败!\n"); return -1; } printf("旧的套接字(监听套接字)是:%d\n",tcpsock); printf("服务器的代码阻塞在accept位置了!\n"); //接收客户端的连接请求 newsock=accept(tcpsock,(struct sockaddr *)&boyaddr,&addrsize); if(newsock==-1) { perror("接收连接请求失败了!\n"); return -1; } printf("有一个客户端连接成功了,产生的新套接字(已连接套接字)是:%d\n",newsock); fd_set myset; while(1) { //由于select会自动剔除没有发送状态改变的文件描述符,所有需要重复添加 FD_ZERO(&myset); FD_SET(newsock,&myset); FD_SET(0,&myset); //调用select监测新的套接字是否有数据可读,键盘是否有输入 ret=select(newsock+1,&myset,NULL,NULL,NULL); if(ret>0) //监测到了状态变化 { //进一步判断究竟是谁(键盘or新的套接字)发生了读就绪 if(FD_ISSET(newsock,&myset)) //newsock在集合--》newsock发生了读就绪 { bzero(rbuf,100); //接收客户端发过来的信息 read(newsock,rbuf,100); printf("客户端发送过来的内容是:%s\n",rbuf); } if(FD_ISSET(0,&myset)) //键盘在集合--》键盘发生了读就绪 { bzero(sbuf,100); scanf("%s",sbuf); write(newsock,sbuf,strlen(sbuf)); } } else { perror("监测失败!\n"); return -1; } } //关闭套接字 close(tcpsock); close(ret); return 0; } 客户端通信实现代码 #include "myhead.h" /* tcp双向通信--》客户端的代码 多路复用使用思路: 1.思考要监测什么文件描述符 --》键盘(跟发送有关) --》套接字(跟接收有关) 2.监测键盘的读就绪 套接字的读就绪 */ int main() { int tcpsock; int ret; char sbuf[100]; char rbuf[100]; //定义ipv4地址体变量存放需要绑定的ip和端口号 struct sockaddr_in bindaddr; bzero(&bindaddr,sizeof(bindaddr)); bindaddr.sin_family=AF_INET; bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //客户端自己的ip bindaddr.sin_port=htons(10000); //客户端的端口号 //定义ipv4地址体变量存放女朋友(服务器)的ip和端口号 struct sockaddr_in girladdr; bzero(&girladdr,sizeof(girladdr)); girladdr.sin_family=AF_INET; girladdr.sin_addr.s_addr=inet_addr("192.168.22.9"); //服务器的ip girladdr.sin_port=htons(20000); //服务器的端口号 //创建tcp套接字 tcpsock=socket(AF_INET,SOCK_STREAM,0); if(tcpsock==-1) { perror("创建tcp套接字失败!\n"); return -1; } int on=1; setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); //绑定客户端自己的ip和端口号 ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr)); if(ret==-1) { perror("绑定ip端口失败了!\n"); return -1; } //拨号连接服务器 ret=connect(tcpsock,(struct sockaddr *)&girladdr,sizeof(girladdr)); if(ret==-1) { perror("连接失败了!\n"); return -1; } fd_set myset; while(1) { //由于select会自动剔除没有发送状态改变的文件描述符,所有需要重复添加 FD_ZERO(&myset); FD_SET(0,&myset); //键盘 FD_SET(tcpsock,&myset); //套接字 //调用select监测键盘是否有输入,监测套接字是否有数据可读 ret=select(tcpsock+1,&myset,NULL,NULL,NULL); if(ret>0) //监测到了状态变化 { //进一步判断究竟是谁(键盘or套接字)发生了状态变化 if(FD_ISSET(0,&myset)) //键盘在集合中--》键盘发生了读就绪 { bzero(sbuf,100); //读取键盘的输入 scanf("%s",sbuf); //发送给服务器 write(tcpsock,sbuf,strlen(sbuf)); } if(FD_ISSET(tcpsock,&myset)) //套接字在集合中--》套接字发生了读就绪 { bzero(rbuf,100); read(tcpsock,rbuf,100); printf("服务器发过来的信息是:%s\n",rbuf); } } else { perror("监测失败!\n"); return -1; } } //关闭套接字 close(tcpsock); return 0; |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |